#include "MOD_DEV_HEADER.h"

/*
	TODO:
			- Hook: ON_CLIENT_AUTH
			- Send both motd and rules
*/

SFile *motd = NULL;
SFile *rules= NULL;

int LoadMotd (const char* fname);
int LoadRules (const char* fname);

size_t SizeOfFile (const char* fname);

void do_MOTD (SUser *me, char tail[TAILSIZE]);
void do_RULES (SUser *me, char tail[TAILSIZE]);
void ReleaseMap (SFile **mmotd);

/* entry */
void aures_init (SModule* module)
{ 
	MODULE_NAME		(module,	"Motd"							);
	MODULE_VERSION	(module,	"1.0 beta"						);
	MODULE_DESC		(module,	"Send rules and motd to user"	);
	MODULE_AUTHOR	(module, 	"Goundy"						);

	if (LoadMotd ("modules/motd.txt") != 0) return;
	if (LoadRules ("modules/rules.txt") != 0) return;

	AddCommand ("motd", do_MOTD, LEVEL_ALL);	
	AddCommand ("rules", do_RULES, LEVEL_ALL);
}

/* clean up */
void aures_cleanup (void)
{
	ReleaseMap (&motd);
	ReleaseMap (&rules);

	DelCommand ("motd");
	DelCommand ("rules");
}

/* stuffs */

int LoadMotd (const char* fname){

 size_t filesize;
 int fd;

	motd = malloc (sizeof (SFile));
		if (motd == NULL){
			fprintf (stderr, "LoadMotd(): out of memory\n");
			return -1;
		}

	filesize = SizeOfFile (fname);
		if (filesize == 0){
			fprintf (stderr, "LoadMotd(): motd file empty\n");
			free (motd);
			motd = NULL;
			return 0;
		}

	fd = open (fname, O_RDONLY);
		if (fd == -1){
			fprintf (stderr, "LoadMotd(): couldn't open %s\n", fname);
			free (motd);
			motd = NULL;
			return -1;
		}

	motd->map = (char*) mmap (NULL, filesize, PROT_READ, MAP_SHARED, fd, 0);
		if (motd->map == NULL){
			fprintf (stderr, "LoadMotd(): couldn't map %s\n", fname);
			close (fd);
			free (motd);
			motd = NULL;
			return -1;
		}
	motd->size = filesize;

 return filesize;
}

int LoadRules (const char* fname){

 size_t filesize;
 int fd;

	rules = malloc (sizeof (SFile));
		if (rules == NULL){
			fprintf (stderr, "LoadRules(): out of memory\n");
			return -1;
		}

	filesize = SizeOfFile (fname);
		if (filesize == 0){
			fprintf (stderr, "LoadRules(): rules file empty\n");
			free (rules);
			rules = NULL;
			return 0;
		}

	fd = open (fname, O_RDONLY);
		if (fd == -1){
			fprintf (stderr, "LoadRules(): couldn't open %s\n", fname);
			free (rules);
			rules = NULL;
			return -1;
		}

	rules->map = (char*) mmap (NULL, filesize, PROT_READ, MAP_SHARED, fd, 0);
		if (rules->map == NULL){
			fprintf (stderr, "LoadRules(): couldn't map %s\n", fname);
			close (fd);
			free (rules);
			rules = NULL;
			return -1;
		}
	rules->size = filesize;

 return filesize;
}

void do_MOTD (SUser *me, char tail[TAILSIZE]){

 char mbuf[512+1], *pmotd=NULL;
 int sentBytes, gard;

	pmotd = motd->map;
	sentBytes = 0;

	gard = SendToUser (me->id, "MOTD Message of the day\r\n");
		if (gard == -2){
			do_KILL (me, "broken pipe");
			return;
		}
		if (gard == -1){
			printf("error send()\n");
			return;
		}

	while (sentBytes < motd->size){
		gard = sscanf (pmotd, "%510[^\n]", mbuf);
			if (gard == 1){
				strcat (mbuf, "\r\n");

				gard = SendToUser (me->id, "MOTD %s\r\n", mbuf);
					if (gard == -2){
						do_KILL (me, "broken pipe");
						break;
					}
					if (gard == -1){
						printf("error send()\n");
						break;
					}

				sentBytes += strlen (mbuf);
				pmotd = pmotd + strlen (mbuf);
			}
	}

	gard = SendToUser (me->id, "MOTD END OF MOTD\r\n");
		if (gard == -2){
			do_KILL (me, "broken pipe");
			return;
		}
		if (gard == -1){
			printf("error send()\n");
			return;
		}

}

void do_RULES (SUser *me, char tail[TAILSIZE]){

 char mbuf[512], *prules=NULL;
 int sentBytes, gard;

	prules = rules->map;
	sentBytes = 0;

	gard = SendToUser (me->id, "RULES START OF RULES\r\n");
		if (gard == -2){
			do_KILL (me, "broken pipe");
			return;
		}
		if (gard == -1){
			printf("error send()\n");
			return;
		}

	while (sentBytes < rules->size){
		gard = sscanf (prules, "%510[^\n]", mbuf);
			if (gard == 1){
				strcat (mbuf, "\r\n");

				gard = SendToUser (me->id, "RULES %s\r\n", mbuf);
					if (gard == -2){
						do_KILL (me, "broken pipe");
						break;
					}
					if (gard == -1){
						printf("error send()\n");
						break;
					}

				sentBytes += strlen (mbuf);
				prules = prules + strlen (mbuf);
			}
	}

	gard = SendToUser (me->id, "RULES END OF RULES\r\n");
		if (gard == -2){
			do_KILL (me, "broken pipe");
			return;
		}
		if (gard == -1){
			printf("error send()\n");
			return;
		}

}

size_t SizeOfFile (const char* fname){

 size_t fsize = 0;
 FILE* fd = NULL;

	fd = fopen (fname, "r");
		if (fd == NULL){
			fprintf (stderr, "SizeOfFile(): %s not found\n", fname);
			fsize = -1;
		}
		else
		{
			fseek (fd, 0, SEEK_END);
			fsize = (size_t) ftell (fd);
			fclose (fd);
			fd = NULL;
		}

 return fsize;
}

void ReleaseMap (SFile **mmotd){
 int gard;

	if (*mmotd == NULL){
		fprintf (stderr, "ReleaseMap(): map not loaded\n");
	}
	else
	{
		gard = munmap ((void*)(*mmotd)->map, (*mmotd)->size);
		if (gard == -1){
			fprintf (stderr, "ReleaseMap(): munmap error\n");
		}
		free (*mmotd);
		*mmotd = NULL;
	}	
}

